// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	"fmt"
	"time"

	"github.com/ServiceWeaver/weaver"
)

// Transaction defines a banking transaction.
type Transaction struct {
	weaver.AutoMarshal
	FromAccountNum string    `gorm:"column:from_acct;not null"`
	FromRoutingNum string    `gorm:"column:from_route;not null"`
	ToAccountNum   string    `gorm:"column:to_acct;not null"`
	ToRoutingNum   string    `gorm:"column:to_route;not null"`
	Amount         int64     `gorm:"column:amount;not null"`
	Timestamp      time.Time `gorm:"column:timestamp;not null"`
}

const centsPerDollar = 100.0

func (t *Transaction) String() string {
	return fmt.Sprintf("%s->$%.2f->%s",
		t.FromAccountNum, float64(t.Amount)/centsPerDollar, t.ToAccountNum)
}

// TransactionWithID annotates model.Transaction with a unique TransactionID.
// This is used by readers of "transaction" table that require the
// transaction_id column in addition to the rest of transaction data.
//
// Note: Ideally we'd like to have a single Transaction struct which would have
// the TransactionID field as well. However, that doesn't work well with gorm,
// since inserts sql statements generated by gorm always specify transaction_id
// as 0 (TransactionID's zero value), resulting in primary key conflicts.
type TransactionWithID struct {
	weaver.AutoMarshal
	Transaction
	TransactionID int64 `gorm:"column:transaction_id;primaryKey;autoIncrement:true"`
}
